package com.financing.wap.weixin.util;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyStore;
import java.util.HashMap;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

import net.sf.json.JSONException;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.financing.wap.dto.DstUserInfoDTO;
import com.financing.wap.util.AliyunOssUtil;
import com.financing.wap.util.DateUtil;
import com.financing.wap.util.EmojiFilterUtil;
import com.financing.wap.util.MP3Util;
import com.financing.wap.util.PropertiesUtils;
import com.financing.wap.weixin.pojo.AccessTicket;
import com.financing.wap.weixin.pojo.AccessToken;
import com.financing.wap.weixin.pojo.Media;
import com.financing.wap.weixin.pojo.MediaUpload;
import com.financing.wap.weixin.pojo.Menu;
import com.financing.wap.weixin.pojo.SendRedPack;
import com.financing.wap.weixin.resp.SendRedPackResp;
import com.financing.wap.weixin.service.impl.CoreServiceImpl;

public class WeixinUtil {

	private static Logger logger = Logger.getLogger(WeixinUtil.class);

	// 获取access_token的接口地址（GET） 限100000（次/天）
	public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
	// 菜单创建（POST） 限1000（次/天）
	public static String menu_create_url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
	// 菜单删除（POST） 限100000（次/天）
	public static String menu_delete_url = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN";
	// 高级群发接口 上传图文消息素材
	public static String media_uploadnews_url = "https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token=ACCESS_TOKEN";
	/**
	 * 高级群发接口 根据分组进行群发
	 */
	public static String message_mass_sendall_url = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token=ACCESS_TOKEN";
	// 上传多媒体文件
	public static String media_upload_url = "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE";
	//移动用户分组
	public static String groups_members_update_url = "https://api.weixin.qq.com/cgi-bin/groups/members/update?access_token=ACCESS_TOKEN";
	
	//开放-微信登陆 (1)生成二维码
	public static String open_weixin_login = "https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
	//开放-微信登陆 (2)获取 access_token
	public static String open_access_token = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
	//开放-微信登陆 (3)获取 access_token
	public static String open_user_info = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID";
	// 获取jsapi_ticket的接口地址（GET） 限200（次/天）
	public final static String jsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
	
    private static final String MESSAGE_URL = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN";
	// 用于企业向微信用户个人发现金红包
	public final static String send_red_pack = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";
	
    //生成带参数的二维码
    
    //创建二维码ticket
    private static final String  create_ticket = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN";
    
    //ticket生成二维码
    public static final String  showqrcode = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET";
    
    //user_info
    private static final String  user_info = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN"; 
    
	/**
	 * token
	 */
	private static String token;
	
	/**
	 * token
	 */
	private static String token_wjt;
	
	/**
	 * Ticket
	 */
	private static String ticket;
	
	/**
	 * Ticket
	 */
	private static String ticket_wjt;
	
	// 间隔时间
	private static int interval = 5 * 60 * 1000; // 80分钟

	// 刷新时间。默认当前时间
	private  static long refreshTime = System.currentTimeMillis();
	
	// 刷新时间。默认当前时间
	private  static long refreshTime_wjt = System.currentTimeMillis();

	// 刷新时间。默认当前时间
	private  static long ticketRefreshTime = System.currentTimeMillis();
	
	// 刷新时间。默认当前时间
	private  static long ticketRefreshTime_wjt = System.currentTimeMillis();
	
	// 从微信服务器下载音频文件地址
	private static String wx_audio_address ="http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID";
	
	//文件到目录
	private static String ossUserCardPath = PropertiesUtils.getValue("ossUserCardPath");

	private static String aliyunOss = PropertiesUtils.getValue("AliyunOss");

	/**
	 * 发起https请求并获取结果
	 * 
	 * @param requestUrl
	 *            请求地址
	 * @param requestMethod
	 *            请求方式（GET、POST）
	 * @param outputStr
	 *            提交的数据
	 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
	 */
	public static JSONObject httpsRequest(String requestUrl,
			String requestMethod, String outputStr) {
		JSONObject jsonObject = null;
		StringBuffer buffer = new StringBuffer();
		try {
			// 创建SSLContext对象，并使用我们指定的信任管理器初始化
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			// 从上述SSLContext对象中得到SSLSocketFactory对象
			SSLSocketFactory ssf = sslContext.getSocketFactory();

			URL url = new URL(requestUrl);
			HttpsURLConnection httpUrlConn = (HttpsURLConnection) url
					.openConnection();
			httpUrlConn.setSSLSocketFactory(ssf);

			httpUrlConn.setDoOutput(true);
			httpUrlConn.setDoInput(true);
			httpUrlConn.setUseCaches(false);
			// 设置请求方式（GET/POST）
			httpUrlConn.setRequestMethod(requestMethod);

			if ("GET".equalsIgnoreCase(requestMethod))
				httpUrlConn.connect();

			// 当有数据需要提交时
			if (null != outputStr) {
				OutputStream outputStream = httpUrlConn.getOutputStream();
				// 注意编码格式，防止中文乱码
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}

			// 将返回的输入流转换成字符串
			InputStream inputStream = httpUrlConn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(
					inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(
					inputStreamReader);

			String str = null;
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}
			bufferedReader.close();
			inputStreamReader.close();
			// 释放资源
			inputStream.close();
			inputStream = null;
			httpUrlConn.disconnect();
			jsonObject = JSONObject.fromObject(buffer.toString());
		} catch (ConnectException ce) {
			logger.error("Weixin server connection timed out.", ce);
		} catch (Exception e) {
			logger.error("https request error:{}", e);
		}
		return jsonObject;
	}

	/**
	 * 发起http请求并获取结果
	 * 
	 * @param requestUrl
	 *            请求地址
	 * @param requestMethod
	 *            请求方式（GET、POST）
	 * @param outputStr
	 *            提交的数据
	 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
	 * @throws Exception
	 */
	public static JSONObject httpRequest(String requestUrl,
			String requestMethod, String outputStr, String type)
			throws Exception {
		JSONObject jsonObject = null;
		// 定义数据分隔符
		String boundary = "------------7da2e536604c8";
		try {
			URL uploadUrl = new URL(requestUrl);
			HttpURLConnection uploadConn = (HttpURLConnection) uploadUrl
					.openConnection();
			uploadConn.setDoOutput(true);
			uploadConn.setDoInput(true);
			uploadConn.setRequestMethod("POST");
			// 设置请求头Content-Type
			uploadConn.setRequestProperty("Content-Type",
					"multipart/form-data;boundary=" + boundary);
			// 获取媒体文件上传的输出流（往微信服务器写数据）
			OutputStream outputStream = uploadConn.getOutputStream();

			URL mediaUrl = new URL(outputStr);
			HttpURLConnection meidaConn = (HttpURLConnection) mediaUrl
					.openConnection();
			meidaConn.setDoOutput(true);
			meidaConn.setRequestMethod("GET");

			// 从请求头中获取内容类型
			String contentType = meidaConn.getHeaderField("Content-Type");
			// 根据内容类型判断文件扩展名
			String fileExt = ".jpg";
			// 请求体开始
			outputStream.write(("--" + boundary + "\r\n").getBytes());
			outputStream
					.write(String
							.format("Content-Disposition: form-data; name=\"media\"; filename=\"file1%s\"\r\n",
									fileExt).getBytes());
			outputStream.write(String.format("Content-Type: %s\r\n\r\n",
					contentType).getBytes());

			// 获取媒体文件的输入流（读取文件）
			BufferedInputStream bis = new BufferedInputStream(
					meidaConn.getInputStream());
			byte[] buf = new byte[8096];
			int size = 0;
			while ((size = bis.read(buf)) != -1) {
				// 将媒体文件写到输出流（往微信服务器写数据）
				outputStream.write(buf, 0, size);
			}
			// 请求体结束
			outputStream.write(("\r\n--" + boundary + "--\r\n").getBytes());
			outputStream.close();
			bis.close();
			meidaConn.disconnect();

			// 获取媒体文件上传的输入流（从微信服务器读数据）
			InputStream inputStream = uploadConn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(
					inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(
					inputStreamReader);
			StringBuffer buffer = new StringBuffer();
			String str = null;
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}
			bufferedReader.close();
			inputStreamReader.close();
			// 释放资源
			inputStream.close();
			inputStream = null;
			uploadConn.disconnect();

			// 使用JSON-lib解析返回结果
			jsonObject = JSONObject.fromObject(buffer.toString());
		} catch (Exception e) {
			logger.error("http request error:{}", e);
		}
		return jsonObject;
	}
	/**
	 * 发起https请求并获取结果
	 * 
	 * @param requestUrl
	 *            请求地址
	 * @param requestMethod
	 *            请求方式（GET、POST）
	 * @param outputStr
	 *            提交的数据
	 * @return Document(通过dom4j的方式获取xml对象的属性值)
	 */
	public static Document httpsRequestForCert(String requestUrl,
			String requestMethod, String outputStr,String certPath,String certNum) {
		Document document = null;
		StringBuffer buffer = new StringBuffer();
		try {
			/*// 创建SSLContext对象，并使用我们指定的信任管理器初始化
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());*/
			
			KeyStore keyStore  = KeyStore.getInstance("PKCS12");
	        FileInputStream instream = new FileInputStream(new File(certPath));
	        try {
	            keyStore.load(instream, certNum.toCharArray());
	        } finally {
	            instream.close();
	        }

	        // Trust own CA and all self-signed certs
	        SSLContext sslcontext = SSLContexts.custom()
	                .loadKeyMaterial(keyStore, certNum.toCharArray())
	                .build();
			// 从上述SSLContext对象中得到SSLSocketFactory对象
			SSLSocketFactory ssf = sslcontext.getSocketFactory();

			URL url = new URL(requestUrl);
			HttpsURLConnection httpUrlConn = (HttpsURLConnection) url
					.openConnection();
			httpUrlConn.setSSLSocketFactory(ssf);

			httpUrlConn.setDoOutput(true);
			httpUrlConn.setDoInput(true);
			httpUrlConn.setUseCaches(false);
			// 设置请求方式（GET/POST）
			httpUrlConn.setRequestMethod(requestMethod);

			if ("GET".equalsIgnoreCase(requestMethod))
				httpUrlConn.connect();

			// 当有数据需要提交时
			if (null != outputStr) {
				OutputStream outputStream = httpUrlConn.getOutputStream();
				// 注意编码格式，防止中文乱码
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}

			// 将返回的输入流转换成字符串
			InputStream inputStream = httpUrlConn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(
					inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(
					inputStreamReader);

			String str = null;
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}
			bufferedReader.close();
			inputStreamReader.close();
			// 释放资源
			inputStream.close();
			inputStream = null;
			httpUrlConn.disconnect();
			document = DocumentHelper.parseText(buffer.toString());
		} catch (ConnectException ce) {
			logger.error("Weixin server connection timed out.", ce);
		} catch (Exception e) {
			logger.error("https request error:{}", e);
		}
		return document;
	}


	/**
	 * 获取access_token
	 * 
	 * @param appid
	 *            凭证
	 * @param appsecret
	 *            密钥
	 * @return
	 */
	public static AccessToken getAccessToken(String appid, String appsecret) {
		AccessToken accessToken = null;

		String requestUrl = access_token_url.replace("APPID", appid).replace(
				"APPSECRET", appsecret);
		JSONObject jsonObject = httpsRequest(requestUrl, "GET", null);
		// 如果请求成功
		if (null != jsonObject) {
			try {
				accessToken = new AccessToken();
				accessToken.setToken(jsonObject.getString("access_token"));
				accessToken.setExpiresIn(jsonObject.getInt("expires_in"));
			} catch (JSONException e) {
				accessToken = null;
				// 获取token失败
				logger.error(
						"getAccessToken error errcode:"
								+ jsonObject.getInt("errcode") + ";errmsg:"
								+ jsonObject.getString("errmsg"), e);
			}
		}
		return accessToken;
	}

	/**
	 * 创建菜单
	 * 
	 * @param menu
	 *            菜单实例
	 * @param accessToken
	 *            有效的access_token
	 * @return 0表示成功，其他值表示失败
	 */
	public static int createMenu(Menu menu, String accessToken) {
		int result = 0;

		// 拼装创建菜单的url
		String url = menu_create_url.replace("ACCESS_TOKEN", accessToken);
		// 将菜单对象转换成json字符串
		String jsonMenu = JSONObject.fromObject(menu).toString();
		// 调用接口创建菜单
		JSONObject jsonObject = httpsRequest(url, "POST", jsonMenu);

		if (null != jsonObject) {
			if (0 != jsonObject.getInt("errcode")) {
				result = jsonObject.getInt("errcode");
				logger.error("createMenu error errcode:"
						+ jsonObject.getInt("errcode") + ";errmsg:"
						+ jsonObject.getString("errmsg"));
			}
		}

		return result;
	}

	/**
	 * 删除菜单
	 * 
	 * @param menu
	 *            菜单实例
	 * @param accessToken
	 *            有效的access_token
	 * @return 0表示成功，其他值表示失败
	 */
	public static int deleteMenu(String accessToken) {
		int result = 0;

		// 拼装删除菜单的url
		String url = menu_delete_url.replace("ACCESS_TOKEN", accessToken);
		// 调用接口删除菜单
		JSONObject jsonObject = httpsRequest(url, "POST", null);

		if (null != jsonObject) {
			if (0 != jsonObject.getInt("errcode")) {
				result = jsonObject.getInt("errcode");
				logger.error("deleteMenu error errcode:"
						+ jsonObject.getInt("errcode") + ";errmsg:"
						+ jsonObject.getString("errmsg"));
			}
		}

		return result;
	}

	/**
	 * 文件上传到微信服务器
	 * 
	 * @param fileType
	 *            媒体文件类型，分别有图片（image）、语音（voice）、视频（video）和缩略图（thumb）
	 * @param filePath
	 *            文件路径
	 * @return JSONObject
	 * @throws Exception
	 */
	public static MediaUpload mediaUpload(String accessToken, String type,
			String filePath) throws Exception {
		MediaUpload mediaUpload = null;
		String requestUrl = media_upload_url.replace("ACCESS_TOKEN",
				accessToken).replace("TYPE", type);
		JSONObject jsonObject = httpRequest(requestUrl, "POST", filePath, null);
		// 如果请求成功
		if (null != jsonObject) {
			try {
				mediaUpload = new MediaUpload();
				mediaUpload.setType(jsonObject.getString("type"));
				mediaUpload.setMedia_id(jsonObject.getString("media_id"));
				mediaUpload.setCreated_at(jsonObject.getString("created_at"));

			} catch (JSONException e) {
				mediaUpload = null;
				logger.error("deleteMenu error errcode:"
						+ jsonObject.getInt("errcode") + ";errmsg:"
						+ jsonObject.getString("errmsg"));
			}
		}
		return mediaUpload;
	}

	/**
	 * 根据分组进行群发
	 * 
	 * @param fileType
	 *            媒体文件类型，分别有图片（image）、语音（voice）、视频（video）和缩略图（thumb）
	 * @param filePath
	 *            文件路径
	 * @return JSONObject
	 * @throws Exception
	 */
	public static int messageMassSendall(String accessToken, Media media)
			throws Exception {
		String requestUrl = message_mass_sendall_url.replace("ACCESS_TOKEN",
				accessToken);
		String jsonMedia = JSONObject.fromObject(media).toString();
		JSONObject jsonObject = httpsRequest(requestUrl, "POST", jsonMedia);
		// 如果请求成功
		if (null != jsonObject) {
			try {
			} catch (JSONException e) {
			}
		}
		return 0;
	}
	/**
	 * 移动用户分组
	 * 
	 * @param map
	 *            参数实例
	 * @param accessToken
	 *            有效的access_token
	 * @return 0表示成功，其他值表示失败
	 */
	public static int groupsMembersUpdate(Map<String,Object> map, String accessToken) {
		int result = 0;

		// 拼装移动用户分组的url
		String url = groups_members_update_url.replace("ACCESS_TOKEN", accessToken);
		// 将map对象转换成json字符串
		String jsonMap = JSONObject.fromObject(map).toString();
		// 调用接口移动用户分组
		JSONObject jsonObject = httpsRequest(url, "POST", jsonMap);

		if (null != jsonObject) {
			if (0 != jsonObject.getInt("errcode")) {
				result = jsonObject.getInt("errcode");
				logger.error("createMenu error errcode:"
						+ jsonObject.getInt("errcode") + ";errmsg:"
						+ jsonObject.getString("errmsg"));
			}
		}

		return result;
	}
	
	/**
	 * 开放-微信登陆 (1) 生成 二维码
	 * 
	 * @param map
	 *            参数实例
	 * @param accessToken
	 *            有效的access_token
	 * @return 0表示成功，其他值表示失败
	 */
	public static String getOpenWeixinLoginURL(String appid,String redirect_uri,String state) {

		// 生成 二维码
		String url = open_weixin_login.replace("APPID", appid)
									  .replace("REDIRECT_URI", redirect_uri)
									  .replace("SCOPE", "snsapi_login")
								      .replace("STATE", state);
		
		return url;
	}
	/**
	 * 开放-微信登陆 (1) 生成 二维码
	 * 
	 * @param map
	 *            参数实例
	 * @param accessToken
	 *            有效的access_token
	 * @return 0表示成功，其他值表示失败
	 */
	public static Map<String,Object>  getOpenAccessToken(String appid,String secret,String code) {

		// 生成 二维码
		String url = open_access_token.replace("APPID", appid)
									  .replace("SECRET", secret)
									  .replace("CODE", code);
		
		// 调用接口删除菜单
		JSONObject jsonObject = httpsRequest(url, "POST", null);
		System.out.println(jsonObject.toString());

		Map<String,Object> map = null;
		if (null != jsonObject) {
			try {
				map = new HashMap<String,Object>();
				map.put("access_token", jsonObject.getString("access_token"));
				map.put("openid", jsonObject.getString("openid"));
			} catch (JSONException e) {
				map = null;
				// 获取token失败
				logger.error(
						"getAccessToken error errcode:"
								+ jsonObject.getInt("errcode") + ";errmsg:"
								+ jsonObject.getString("errmsg"), e);
			}
		}
		
		return map;
	}
	/**
	 * 开放-微信登陆 (1) 生成 二维码
	 * 
	 * @param map
	 *            参数实例
	 * @param accessToken
	 *            有效的access_token
	 * @return 0表示成功，其他值表示失败
	 */
	public static DstUserInfoDTO  getOpenUserinfo(String access_token,String openid) {

		// 生成获取 微信 用户信息url
		String url = open_user_info.replace("ACCESS_TOKEN", access_token)
									  .replace("OPENID", openid);
		
		// 调用接口删除菜单
		JSONObject jsonObject = httpsRequest(url, "POST", null);

		DstUserInfoDTO userInfo = null;
		if (null != jsonObject) {
			try {
				userInfo = new DstUserInfoDTO();
				userInfo.setUserWechatOpenid(jsonObject.getString("openid"));
				userInfo.setUserName(EmojiFilterUtil.filterEmoji(jsonObject.getString("nickname")));
				userInfo.setUserWechatImage(jsonObject.getString("headimgurl"));
				userInfo.setUserWechatAddress(jsonObject.getString("province")+jsonObject.getString("city"));
			} catch (JSONException e) {
				// 获取token失败
				logger.error(
						"getAccessToken error errcode:"
								+ jsonObject.getInt("errcode") + ";errmsg:"
								+ jsonObject.getString("errmsg"), e);
			}
		}
		
		return userInfo;
	}
	
	/**
     * 发送客服消息
     *
     * @param accessToken
     * @param message
     * @return
     * @throws Exception
     */
	public static  Map<String,Object> sendMsg(String accessToken, Map<String, Object> message) throws Exception {
		// 拼装移动用户分组的url
		String url = MESSAGE_URL.replace("ACCESS_TOKEN", accessToken);
		// 将map对象转换成json字符串
		String jsonMap = JSONObject.fromObject(message).toString();
		// 调用接口移动用户分组
		JSONObject jsonObject = httpsRequest(url, "POST", jsonMap);
		Map<String,Object> map = null;
		if (null != jsonObject) {
			try {
				map = new HashMap<String,Object>();
				map.put("errcode", jsonObject.getInt("errcode"));
				map.put("errmsg", jsonObject.getString("errmsg"));
			} catch (JSONException e) {
				map = null;
				// 获取token失败
				logger.error(
						"getAccessToken error errcode:"
								+ jsonObject.getInt("errcode") + ";errmsg:"
								+ jsonObject.getString("errmsg"), e);
			}
		}
		
		return map;
    }
    
    /**
     * 发送文本客服消息
     *
     * @param openId
     * @param text
     * @throws Exception
     */
	public static String sendText(String accessToken, String openId, String text) throws Exception {
        Map<String, Object> json = new HashMap<String, Object>();
        Map<String, Object> textObj = new HashMap<String, Object>();
        textObj.put("content", text);
        json.put("touser", openId);
        json.put("msgtype", "text");
        json.put("text", textObj);
        Map<String, Object> sendMsg = sendMsg(accessToken, json);
        return sendMsg.toString();
    }
	
	
	 /**
     * 发送图片客服消息
     *
     * @param openId
     * @param text
     * @throws Exception
     */
	public static String sendMedia(String accessToken, String openId, String text) throws Exception {
        Map<String, Object> json = new HashMap<String, Object>();
        Map<String, Object> textObj = new HashMap<String, Object>();
        textObj.put("media_id", text);
        json.put("touser", openId);
        json.put("msgtype", "image");
        json.put("image", textObj);
        sendMsg(accessToken, json);
        return null;
    }
	/**
	 * 获取getCreateTicket
	 * 
	 * @param appid
	 *            凭证
	 * @param appsecret
	 *            密钥
	 * @return
	 */
	public static Map<String,Object> getCreateTicket(String access_token,String userId) {

		String requestUrl = create_ticket.replace("TOKEN", access_token);
		
		JSONObject jsonObject = httpsRequest(requestUrl, "POST", "{\"expire_seconds\": 2592000, \"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": "+userId+"}}}");
		
		Map<String,Object> map = null;
		// 如果请求成功
		if (null != jsonObject) {
			try {
				map = new HashMap<String,Object>();
				map.put("ticket", jsonObject.getString("ticket"));
				map.put("expire_seconds", jsonObject.getString("expire_seconds"));
				map.put("url", jsonObject.getString("url"));
			} catch (JSONException e) {
				// 获取token失败
				logger.error(
						"getAccessToken error errcode:"
								+ jsonObject.getInt("errcode") + ";errmsg:"
								+ jsonObject.getString("errmsg"), e);
			}
		}
		return map;
	}
	
	/**
	 * 获取access_ticket
	 * 
	 * @param AccessToken
	 * @return
	 */
	public static AccessTicket getAccessTicket(String accessToken) {
		AccessTicket accessTicket = null;

		String requestUrl = jsapi_ticket_url.replace("ACCESS_TOKEN", accessToken);
		JSONObject jsonObject = httpsRequest(requestUrl, "GET", null);
		// 如果请求成功
		if (null != jsonObject) {
			try {
				accessTicket = new AccessTicket();
				accessTicket.setTicket(jsonObject.getString("ticket"));
				accessTicket.setExpiresIn(jsonObject.getInt("expires_in"));
			} catch (JSONException e) {
				accessToken = null;
				// 获取token失败
				logger.error(
						"getAccessTicket error errcode:"
								+ jsonObject.getInt("errcode") + ";errmsg:"
								+ jsonObject.getString("errmsg"), e);
			}
		}
		return accessTicket;
	}
	/**
	 * 获取 token
	 * @return
	 */
	public synchronized static String getToken(String appid,String secret) {
		return checkAccessToken(appid,secret);
	}
	
	/**
	 * 获取 token
	 * @return
	 */
	public synchronized static String getTokenWjt(String appid,String secret) {
		return checkAccessTokenWjt(appid,secret);
	}
	
	/**
	 * 获取 token
	 * @return
	 */
	public synchronized static String getTicket(String appid,String secret) {
		return checkAccessTicket(appid,secret);
	}
	
	/**
	 * 获取 token
	 * @return
	 */
	public synchronized static String getTicketWjt(String appid,String secret) {
		return checkAccessTicketWjt(appid,secret);
	}
	
	private static String checkAccessToken(String appid,String secret) {
		long current = System.currentTimeMillis();
		if (refreshTime < current || token == null) {

			logger.info("checkAccessToken refreshTime begin");

			refreshTime = getNextRefreshTime(current, interval);
			// 1、获取access_token
			AccessToken accessToken = WeixinUtil.getAccessToken(appid,secret);
			token = accessToken.getToken();
			logger.info("checkAccessToken refreshTime end");

		}
		return token;
	}
	
	private static String checkAccessTokenWjt(String appid,String secret) {
		long current = System.currentTimeMillis();
		if (refreshTime_wjt < current || token_wjt == null) {

			logger.info("checkAccessTokenWjt refreshTime_wjt begin");

			refreshTime_wjt = getNextRefreshTime(current, interval);
			// 1、获取access_token
			AccessToken accessToken = WeixinUtil.getAccessToken(appid,secret);
			token_wjt = accessToken.getToken();
			logger.info("checkAccessTokenWjt refreshTime_wjt end");

		}
		return token_wjt;
	}
	private static String checkAccessTicket(String appid,String secret) {
		long current = System.currentTimeMillis();
		if (ticketRefreshTime < current || ticket == null) {

			logger.info("checkAccessTokenAndTicket getNextRefreshTime begin");

			ticketRefreshTime = getNextRefreshTime(current, interval);
			// 1、获取access_token
			String token = getToken(appid,secret);
			// 2、获取jsapi_ticket
			AccessTicket accessTicket = getAccessTicket(token);
			ticket = accessTicket.getTicket();
			logger.info("checkAccessTokenAndTicket getNextRefreshTime end");

		}
		return ticket;
	}
	
	private static String checkAccessTicketWjt(String appid,String secret) {
		long current = System.currentTimeMillis();
		if (ticketRefreshTime_wjt < current || ticket_wjt == null) {

			logger.info("checkAccessTicketWjt ticketRefreshTime_wjt begin");

			ticketRefreshTime_wjt = getNextRefreshTime(current, interval);
			// 1、获取access_token
			String token = getToken(appid,secret);
			// 2、获取jsapi_ticket
			AccessTicket accessTicket = getAccessTicket(token);
			ticket_wjt = accessTicket.getTicket();
			logger.info("checkAccessTicketWjt ticketRefreshTime_wjt end");

		}
		return ticket_wjt;
	}
	/**
	 * 获得下一个刷新时间。
	 * 
	 * @param current
	 * @param interval
	 * @return 随机间隔时间
	 */
	private static long getNextRefreshTime(long current, int interval) {
		return current + interval;
		// 为了防止多个应用同时刷新，间隔时间=interval+RandomUtils.nextInt(interval/4);
		// return current + interval + RandomUtils.nextInt(interval / 4);
	}
	
	public static void main(String[] args) throws Exception {
//		AccessToken accessToken = WeixinUtil.getAccessToken("wxa43920a2a7d39e1b", "e98a3c6e9f22b2b15f02566d3f8e3cb4");
//		token = accessToken.getToken();
//		System.out.println(token);
//		DstUserInfoDTO openUserinfo = getOpenUserinfo(token, "ouBOIt1rXyc8Bmffg8mJ4ltZa94k");
//		System.out.println(openUserinfo);
		
		String picAddr = WeixinUtil.getFileByMediaId("jpg", "1237378768e7q8e7r8qwesafdasdfasdfaxss111", CoreServiceImpl.appid, CoreServiceImpl.secret);
		System.out.println(picAddr);
		
//		MediaUpload m = mediaUpload("ECM-oOWMor9nPrMiXlgvv4RYtT8aCiMCnDKOCO4qR0IlF0ahhowAVVw8nrTe_BqU04hbEo1svfBDU1CcesskMWh4uSoRRwjrOo4JsYFmQZyWQmcmiy152rHZa5LWk1kHKGFiAFASON", "image", "E:\\20160801103833.jpg");
//		System.out.println(m.getMedia_id());
//		System.out.println(m.getType());
//		getFileByMediaId("amr", "zLv--_7UHZao8Do8VG7k50ihou6QgGRekqsPK9XLfsghpLVFosY1NcZkIp6_1a56", "wxad1ea380284b2b48", "ebdb41291cee81e10d64e86295675a13");
		
		
	}
	/**
	 * 根据mediaId获取下载文件到本地
	 * @param string
	 * @return 本地文件地址
	 */
	public static String getFileByMediaId(String docFormat, String audioMediaId, String appid, String secret) {
		String convertedMp3 = "";
		// 获取当前生效token
		String tokenString = getTokenWjt(appid, secret);
		// 拼接目标UR
		String requestUrl = wx_audio_address.replace("ACCESS_TOKEN", tokenString).replace(
				"MEDIA_ID", audioMediaId);
		// 文件分隔符
		String separator = File.separator;

		// 生成本地服务器存放目录
		StringBuffer fileFullPath = new StringBuffer();
		fileFullPath.append(ossUserCardPath)
				.append(separator)
				.append(DateUtil.getDate());
		fileFullPath.append(separator)
				.append(audioMediaId)
				.append("_")
				.append(System.currentTimeMillis())
				.append(".")
				.append(docFormat);

		// 下载对应音频文件
		URL url;
		InputStream is = null;
		OutputStream os = null;
		try {
			logger.info("fileUpload.shtml  requestUrl:"+requestUrl);
			url = new URL(requestUrl);
			URLConnection con = url.openConnection();
			is = con.getInputStream();

			//判断 是否-oss
			logger.info("  AliyunOss:"+aliyunOss);
			if(!"true".equals(aliyunOss)) {
				os = new FileOutputStream(fileFullPath.toString());
				logger.info("amr fileFullPath:"+fileFullPath.toString());

				logger.info("requestUrl:"+requestUrl);
				byte[] bs = new byte[1024];
				int len;
				while((len = is.read(bs))!=-1){
					os.write(bs, 0, len);
				}
				if(docFormat.equals("amr")){
					logger.info("amr to mp3");
					// 将amr格式转化为mp3格式
					convertedMp3 = MP3Util.convertAmrToMp3(fileFullPath.toString(), "");
				}else{
					return fileFullPath.toString().replaceAll("/disk","");
				}
			}else{

				if(docFormat.equals("amr")){
					os = new FileOutputStream(fileFullPath.toString());
					logger.info("amr fileFullPath:"+fileFullPath.toString());

					logger.info("requestUrl:"+requestUrl);
					byte[] bs = new byte[1024];
					int len;
					while((len = is.read(bs))!=-1){
						os.write(bs, 0, len);
					}
					logger.info("amr to mp3");
					// 将amr格式转化为mp3格式
					convertedMp3 = MP3Util.convertAmrToMp3(fileFullPath.toString(), "");

					AliyunOssUtil.writeFile(new FileInputStream(new File(convertedMp3)), StringUtils.replace(convertedMp3.toString(),"/disk/",""));
				}else{
					AliyunOssUtil.writeFile(is, StringUtils.replace(fileFullPath.toString(),"/disk/",""));
					return fileFullPath.toString().replaceAll("/disk","");
				}

			}


		} catch (Exception e) {
			logger.error("download audio file fail !! mediaId = " + audioMediaId,e);
		} finally {
			try {
				if(os != null) {
					os.close();
				}
				if(is != null){
					is.close();
				}

			} catch (IOException e) {
				logger.error("download audio file - close Stream faile");
			}
		}
		
		return convertedMp3.replaceAll("/disk","");
	}
}
